home *** CD-ROM | disk | FTP | other *** search
- ' Cafe engine v0.9 b5
- ' Raycasting routine
- '
- ' Written by Adam Parrott © 1997
- ' Copyright © 1997 Parrottsoft, Ltd.
- '
- ' Raycasting routine to:
- ' 1. Cast rays in x-y planes
- ' 2. Draw walls (orthogonal-90°)
- ' 3. Return needed info to Cafe engine
- '
- ' This program is protected under copyright law
- ' from provision of the United States government
- ' and national and international treaties.
- '
- ' P.S. Inserted are some comments and Rem(s)
- ' everywhere I could so as to help you in
- ' figuring out my variables and the engine setup.
-
- Set Buffer 128 : Degree
- Dim MAP(4096),XNEXT(360),YNEXT(360),DISTTBL(4096)
-
- ' Load Iff "<Your texture here>",2
-
- ' You can change to anything you want,
- ' although at this point, since I don't
- ' have the distance, there is no texture
- ' mapping, although there will be later.
-
- ' Open the screen for drawing.
- Screen Open 1,320,200,64,Lowres
- Flash Off : Curs Off : Cls 0
-
- ' Open the main-display screen.
- Screen Open 0,320,200,64,Lowres
- Flash Off : Curs Off : Cls 0
-
- ' Get Palette 2
- 'Screen Hide 2
- Screen Hide 1
- Screen Show 0
-
- Global MAP(),X,Y,A,ANG,ANGLE,WLDIST
- Global MAPPOS,MAP_XPOS,MAP_YPOS,DISTTBL()
- Global CASTING,SLICE,GRID_SIZE,DETAIL
- Global DEPTH,XDIST,YDIST,XNEXT,YNEXT
- Global XDEPTH,YDEPTH,XDELTA,YDELTA,IK
- Global XBOUND,YBOUND,RAYDEP,NHS,CSA
- Global XNEXT(),YNEXT(),XC,XCI,ANGLEST
-
- Open In 1,"Ram:x_Tantbl.asc"
- For A=1 To 360 : Input #1,XNEXT(A) : Next A : Close 1
- ' This opens in and reads the x-Tan table
-
- Open In 1,"Ram:y_Tantbl.asc"
- For B=0 To 360 : Input #1,YNEXT(B) : Next B : Close 1
- ' This opens in and reads the y-Tan table
-
- ' For C=1 To 4096 : DISTTBL(C)=(2047/C) : Next C
- ' Rem Setup distance table for walls in DistTbl()
- ' This was a distance table I had set up.
-
- Paper 0
- For M=0 To 20
- MAP(M)=3 : Next
-
- XCI=0 : XC=0 : IK=22
- X=200 : Y=200 : A=270
- DETAIL=5 : RAYCAST[X,Y,A]
-
- ' XCI = Increments ANGLE(s) i.e.
- ' XCI = 5, therefore if XCI=5, then Inc Angle
- ' and cast new ray. With 320 columns, cast an
- ' ray, then if XCI=5, then draw the same wall
- ' slice 5 times (same thing for 5 columns), then
- ' exit loop, and cast new ray, looping the process.
-
- ' XC = Screen column. (XColumn)
- ' IK = InK number for drawing.
- ' A = Current facing angle
-
- ' DETAIL = Pretty self-explanatory. Lower the number,
- ' the great the detail, and the longer it takes (to draw/
- ' update the screen, as shown in the loop at bottom.)
-
- Do
- If Inkey$="4" Then X=X-10 : RAYCAST[X,Y,A]
- If Inkey$="6" Then X=X+10 : RAYCAST[X,Y,A]
- If Jup(1) Then Y=Y-10 : RAYCAST[X,Y,A]
- If Jdown(1) Then Y=Y+10 : RAYCAST[X,Y,A]
- If Jleft(1) Then A=A-5 : RAYCAST[X,Y,A]
- If Jright(1) Then A=A+5 : RAYCAST[X,Y,A]
- Loop
-
- ' As shown above, I don't have a fully functional
- ' "moving" algorithm implemented, but I will in
- ' the future, as with the tmapping one as well. The
- ' about routine is just a crude way of getting basic
- ' movement, since I'm usually testing in y-plane anyhow!
-
- ' Much of the following procedure has been modelled
- ' after John Bintz's original raycasting routine, as
- ' I examined it first, then used some of it's basic
- ' concepts that are universal in raycasting and my book.
-
- Procedure RAYCAST[X,Y,ANG]
- ANGLE=((ANG-32+360) mod 360)
- ANGST=((ANG+32+360) mod 360)
- CORNER=0 : GRID_SIZE=64
- MAP_XPOS=X : MAP_YPOS=Y
-
- CSA=-32 : Screen 1 : Cls 0
- Ink 15 : Bar 0,0 To 320,100
- Ink 2 : Bar 0,100 To 320,200
-
- Repeat
-
- ' Get immediate map pos.
- If ANGLE>90 and ANGLE<270
- MAP_XPOS=(MAP_XPOS/64)*64 : Else
- MAP_XPOS=((MAP_XPOS/64)*64)+64 : End If
-
- YNEXT=YNEXT(ANGLE)
- MAP_YPOS=MAP_YPOS+YNEXT
-
- ' Setup for Delta vars
- If ANGLE>90 and ANGLE<270
- XDELTA=-GRID_SIZE : Else
- XDELTA=GRID_SIZE : End If
-
- CASTING=-1
-
- Repeat
- ' Uncomment this to see the actual
- ' rays being cast on the screen.
-
- ' Draw X/5,Y/5 To MAP_XPOS/5,MAP_YPOS/5
- MAPPOS=(MAP_YPOS/64)*64+(MAP_XPOS/64)
-
- If MAPPOS<0 Then MAPPOS=0 : CASTING=0
- If MAPPOS>4096 Then MAPPOS=4096 : CASTING=0
-
- If MAP(MAPPOS)>1 : CASTING=0
- XDIST=MAP_XPOS-X : Else
- XDIST=0 : CASTING=-1 : End If
-
- If CASTING : MAP_XPOS=MAP_XPOS+XDELTA
- MAP_YPOS=MAP_YPOS+YNEXT : End If
-
- If MAP_XPOS<0 Then MAP_XPOS=0 : CASTING=0
- If MAP_XPOS>4096 Then MAP_XPOS=4096 : CASTING=0
-
- If MAP_YPOS<0 Then MAP_YPOS=0 : CASTING=0
- If MAP_YPOS>4096 Then MAP_YPOS=4096 : CASTING=0
-
- Until Not CASTING
-
- CASTING=-1
- MAP_XPOS=X
- MAP_YPOS=Y
-
- ' Get Immediate map pos.
- If ANGLE>0 and ANGLE<180
- MAP_YPOS=((MAP_YPOS/64)*64)+64 : Else
- MAP_YPOS=(MAP_YPOS/64)*64 : End If
-
- XNEXT=XNEXT(ANGLE)
- MAP_XPOS=MAP_XPOS+XNEXT
-
- If ANGLE>0 and ANGLE<180
- YDELTA=GRID_SIZE : Else
- YDELTA=-GRID_SIZE : End If
-
- Repeat
- 'Draw X/5,Y/5 To MAP_XPOS/5,MAP_YPOS/5
- MAPPOS=(MAP_YPOS/64)*64+(MAP_XPOS/64)
-
- If MAPPOS<0 Then MAPPOS=0 : CASTING=0
- If MAPPOS>4096 Then MAPPOS=4096 : CASTING=0
-
- If MAP(MAPPOS)>1 : CASTING=0
- YDIST=MAP_YPOS-Y : Else
- YDIST=0 : CASTING=-1 : End If
-
- If CASTING : MAP_XPOS=MAP_XPOS+XNEXT
- MAP_YPOS=MAP_YPOS+YDELTA : End If
-
- If MAP_XPOS<0 Then MAP_XPOS=0 : CASTING=0
- If MAP_XPOS>4096 Then MAP_XPOS=4096 : CASTING=0
-
- If MAP_YPOS<0 Then MAP_YPOS=0 : CASTING=0
- If MAP_YPOS>4096 Then MAP_YPOS=4096 : CASTING=0
-
- Until Not CASTING
-
- ' According to my book, the routine calls for
- ' the *inverse* Sine and Cosine of the angles.
-
- XDIST=XDIST*-Cos(ANGLE)
- YDIST=YDIST*-Sin(ANGLE)
-
- ' Determine which wall is closer, the x
- ' or y wall, then pass that onto WLDIST.
-
- If YDIST<XDIST
- WLDIST=YDIST : SLICE=YDIST/64 : IK=4 : Else
- WLDIST=XDIST : SLICE=XDIST/64 : IK=5 : End If
-
- ' WLDIST is "Wall DISTance",
- ' as you can probably tell..
-
- ' NHS was derived from the old term
- ' "New Half Size". It caught on, and
- ' it's short, so I used it.
-
- NHS=Abs(WLDIST)*Cos(CSA)
-
- ' As in most casters, here I'm multiplying
- ' by the Cosine of the current casing angle,
- ' starting at -32 and going upto 32 (the entire
- ' number of angles in your Field of View),
- ' as explained ealier in the Readme file.
-
- For S=1 To DETAIL
- ' <Insert your distance routine here>
- ' <Insert your distance routine here>
- ' <Insert your distance routine here>
-
- ' This is pretty much where I'm stuck.
- ' Tried using distance tables, which
- ' worked ok on y-walls, but not on
- ' x-walls. This is what not's working.
-
- Screen 1 : Cls IK,XC,100-NHS To XC+1,100+NHS
- Inc XCI : If XCI=5 : XCI=0
- Inc ANGLE : Inc CSA : End If
-
- Inc XC : MAP_XPOS=X : MAP_YPOS=Y
- ANGLE=((ANGLE+360) mod 360)
-
- Next S : Rem Loops according to DETAIL variable
-
- 'Screen 0 : Ink 1 : Paper 0
- 'Locate 0,22 : Print "NHS:";NHS;Space$(4)
- 'Locate 15,22 : Print "A:";A;Space$(6)
- 'Locate 0,23 : Print "X:";X;Space$(1)
- 'Locate 6,23 : Print "Y:";Y;Space$(4)
- 'Locate 15,23 : Print "MAPPOS:";MAPPOS;Space$(3)
-
- Until ANGLE=ANGST : XC=0
- Screen Copy 1 To 0
-
- End Proc : Rem End raycasting procedure
-